package cn.hd.userService.service.function.impl;

import cn.hd.commonService.entity.SysFunction;
import cn.hd.commonService.entity.SysRoleFunc;
import cn.hd.commonService.exception.CustomException;
import cn.hd.commonService.vo.function.FunctionAuthorityVo;
import cn.hd.userService.mapper.function.SysFunctionMapper;
import cn.hd.userService.service.function.ISysFunctionService;
import cn.hd.userService.service.role.SysRoleFuncService;
import cn.hd.userService.vo.function.FunctionInfoVo;
import cn.hd.userService.vo.function.FunctionVo;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author hd
 * @since 2022-06-26
 */
@Service
public class SysFunctionServiceImpl extends ServiceImpl<SysFunctionMapper, SysFunction> implements ISysFunctionService {
    @Autowired
    private SysFunctionMapper sysFunctionMapper;

    @Autowired
    private SysRoleFuncService sysRoleFuncService;

    /**
     * 保存或修改角色
     * @CreatedBy dsl
     */
    public void saveOrUpdateFunction(SysFunction sysFunction){
        if (StrUtil.isBlankIfStr(sysFunction.getRecordId())){
            sysFunction.setOrderNo(maxOrderNo());
        }
        checkFunction(sysFunction);
        saveOrUpdate(sysFunction);
    }

    /**
     * 验证功能是否合法(需完善)
     * @CreatedBy dsl
     */
    public void checkFunction( SysFunction sysFunction){
        switch (sysFunction.getFuncType()){
            case "1"://目录
                if (StrUtil.isBlankIfStr(sysFunction.getIcon())){
                    throw new CustomException("当前功能类型为目录时，图标不能为空");
                }
                break;
            case "2"://菜单
                if (StrUtil.isBlankIfStr(sysFunction.getParentId())){
                    throw new CustomException("菜单所属目录不能为空");
                }
                if (StrUtil.isBlankIfStr(sysFunction.getComponent())){
                    throw new CustomException("组件名称不能为空");
                }
                if (StrUtil.isBlankIfStr(sysFunction.getCode())){
                    throw new CustomException("组件地址不能为空");
                }
                break;
            case "3"://按钮
            case "4"://url
                if (StrUtil.isBlankIfStr(sysFunction.getParentId())){
                    throw new CustomException("资源所属菜单不能为空");
                }
                if (StrUtil.isBlankIfStr(sysFunction.getCode())){
                    throw new CustomException("资源代码值不能为空");
                }
                break;
        }
        LambdaQueryWrapper<SysFunction> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysFunction::getFuncName,sysFunction.getFuncName()).eq(SysFunction::getDeleted,0);
        SysFunction one = sysFunctionMapper.selectOne(wrapper);

        if (one!=null){
            if (!StrUtil.isBlankIfStr(sysFunction.getRecordId())){
                if (!one.getRecordId().equals(sysFunction.getRecordId())){
                    throw new CustomException("功能名称重复");
                }
            }else {
                throw new CustomException("功能名称重复");
            }
        }

    }

    public void batchDelete(String functionIds){
        //将字符串转化为集合
        List<Integer> list = Convert.toList(Integer.class, functionIds);
        List<SysRoleFunc> sysRoleFuncs = sysRoleFuncService.getList(list);
        if (sysRoleFuncs!=null&&sysRoleFuncs.size()>0){
            throw new CustomException("当前功能关联的有角色，不能删除");
        }
        if (judgeOfChildren(list)){
            throw new CustomException("当前功能下关联的有菜单或资源不能删除");
        }
        //批量删除
        sysFunctionMapper.deleteBatchIds(list);
    }

    /**
     * 分页获取功能数据
     * @return
     */
    public List<FunctionInfoVo> getFunctionList(FunctionVo functionVo){
       return sysFunctionMapper.getFunctionList(functionVo.getParentId(),Convert.toList(String.class,functionVo.getFuncType()));
    }
    /**
     * 获取最大排序号
     * @return
     */
    public int maxOrderNo(){
        return Convert.toInt(sysFunctionMapper.maxOrderNo(),0)+1;
    }

    /**
     * 根据用户id获取权限信息
     * @param userId
     * @return
     */
    @Override
    public List<FunctionAuthorityVo> getAuthorityListByUserId(Integer userId) {
        List<FunctionAuthorityVo> list = sysFunctionMapper.getAuthorityListByUserId(userId);
        list.forEach(functionAuthorityVo -> {
            if (functionAuthorityVo.getParentId().equals("-1")){//表示是父级目录
                //获取目录下的菜单
                List<FunctionAuthorityVo> childrenList = list.stream().filter(functionVo -> {
                    return functionVo.getType() == 2 && functionVo.getParentId().equals(functionAuthorityVo.getRecordId());
                }).collect(Collectors.toList());
                functionAuthorityVo.setChildrenList(childrenList);
            }
        });
        return list;
    }

    public List<SysFunction> getFunctionParentList(String funcType,String functionName,String parentId){
        LambdaQueryWrapper<SysFunction> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysFunction::getFuncType,funcType);
        if (!StrUtil.isBlankIfStr(functionName)){
            wrapper.eq(SysFunction::getFuncName,functionName);
        }
        if (!StrUtil.isEmptyIfStr(parentId)){
            wrapper.eq(SysFunction::getParentId,parentId);
        }
       return sysFunctionMapper.selectList(wrapper);
    }

    /**
     * 启用或禁用功能
     * @param functionId
     * @param flag 1:启用，0：禁用
     */
    public void enableFunction(int functionId,int flag){
        SysFunction sysFunction = sysFunctionMapper.selectById(functionId);
        if (sysFunction == null){
            throw new CustomException("功能信息有误");
        }
        sysFunction.setEnable(flag);
        sysFunctionMapper.updateById(sysFunction);
    }

    /**
     * 判断当前功能下是否有孩子
     * @param functionList
     * @returnn true:有，false：没有
     */
    public boolean judgeOfChildren(List<Integer> functionList){
        LambdaQueryWrapper<SysFunction> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SysFunction::getParentId,functionList);
        wrapper.eq(SysFunction::getDeleted,0);
        List<SysFunction> sysFunctions = sysFunctionMapper.selectList(wrapper);
        if (sysFunctions != null && !sysFunctions.isEmpty()){
            return true;
        }
        return  false;
    }

    public List<SysFunction> getFunctionList(List<Integer> functionId){
        return sysFunctionMapper.selectBatchIds(functionId);
    }
}
